# -*- coding: utf-8 -*-

"""Base class for text/image/table blocks."""
"""文本/图像/表格块的基类。
"""

from .share import BlockType, TextAlignment
from .Element import Element
from .printPro import printPro
import datetime

"""
Block类是具体的文档内容单元，包括文本块（TextBlock）、图像块（ImageBlock）和表格块（TableBlock）的父类
raw中的基本内容提取
Block块类型的识别
格式和样式管理
store方法
"""
class Block(Element):
    """Base class for text/image/table blocks.

    Attributes:
        raw (dict): initialize object from raw properties.
        parent (optional): parent object that this block belongs to.
    """

    """文本/图像/表格块的基类。

    属性:
        raw (dict): 从原始属性初始化对象。
        raw示例：
        
        文本对应的type为0
        主要有number、type、lines属性
        
        图片对应的type为1
        主要有type、bbox、width、height、image
        
        parent (可选): 该块所属的父对象。
    """

    def __init__(self, raw: dict = None, parent=None):
        # 块类型
        self._type = BlockType.UNDEFINED

        # horizontal spacing
        # 水平间距
        if raw is None:
            raw = {}

        if raw.get("type") is not None:
            printPro(
                raw,
                f'raw_{raw.get('type')}_{raw.get('bbox')}_{datetime.datetime.now().strftime("%f")}.py',
                folder=f"block/{BlockType(raw.get('type')).name.lower()}",
            )
        
        # 从raw中提取信息    
        
        # 获取对齐方式
        self.alignment = self._get_alignment(raw.get("alignment", 0))
        # 左侧间距
        self.left_space = raw.get("left_space", 0.0)
        # 右侧间距
        self.right_space = raw.get("right_space", 0.0)
        self.first_line_space = raw.get("first_line_space", 0.0)

        # RELATIVE position of tab stops
        # 制表位的相对位置
        self.tab_stops = raw.get("tab_stops", [])

        # vertical spacing
        # 垂直间距
        self.before_space = raw.get("before_space", 0.0)
        self.after_space = raw.get("after_space", 0.0)
        self.line_space = raw.get("line_space", 0.0)
        self.line_space_type = raw.get("line_space_type", 1)  # 0-exactly, 1-relatively
        # 0-精确值, 1-相对值

        super().__init__(raw, parent)

    @property
    def is_text_block(self):
        """Whether test block."""
        """是否为文本块。"""
        return self._type == BlockType.TEXT

    @property
    def is_inline_image_block(self):
        """Whether inline image block."""
        """是否为内联图像块。"""
        return self._type == BlockType.IMAGE

    @property
    def is_float_image_block(self):
        """Whether float image block."""
        """是否为浮动图像块。"""
        return self._type == BlockType.FLOAT_IMAGE

    @property
    def is_image_block(self):
        """Whether inline or float image block."""
        """是否为内联或浮动图像块。也就是图像块"""
        return self.is_inline_image_block or self.is_float_image_block

    @property
    def is_text_image_block(self):
        """Whether text block or inline image block."""
        """是否为文本块或内联图像块。"""
        return self.is_text_block or self.is_inline_image_block

    @property
    def is_lattice_table_block(self):
        """Whether lattice table (explicit table borders) block."""
        """是否为格子表格（显式表格边框）块。"""
        return self._type == BlockType.LATTICE_TABLE

    @property
    def is_stream_table_block(self):
        """Whether stream table (implied by table content) block."""
        """是否为流式表格（由表格内容隐含）块。"""
        return self._type == BlockType.STREAM_TABLE

    @property
    def is_table_block(self):
        """Whether table (lattice or stream) block."""
        """是否为表格（格子或流式）块。"""
        return self.is_lattice_table_block or self.is_stream_table_block

    def set_text_block(self):
        """Set block type."""
        """设置块类型。"""
        self._type = BlockType.TEXT

    def set_inline_image_block(self):
        """Set block type."""
        """设置块类型。"""
        self._type = BlockType.IMAGE

    def set_float_image_block(self):
        """Set block type."""
        """设置块类型。"""
        self._type = BlockType.FLOAT_IMAGE

    def set_lattice_table_block(self):
        """Set block type."""
        """设置块类型。"""
        self._type = BlockType.LATTICE_TABLE

    def set_stream_table_block(self):
        """Set block type."""
        """设置块类型。"""
        self._type = BlockType.STREAM_TABLE

    def _get_alignment(self, mode: int):
        for t in TextAlignment:
            if t.value == mode:
                return t
        return TextAlignment.LEFT

    def parse_horizontal_spacing(self, bbox, *args):
        """Set left alignment, and calculate left space.

        Override by :obj:`pdf2docx.text.TextBlock`.

        Args:
            bbox (fitz.rect): boundary box of this block.
        """
        """设置左对齐，并计算左侧空间。
        
        被 :obj:`pdf2docx.text.TextBlock` 重写。

        参数:
            bbox (fitz.rect): 此块的边界框。
        """
        # NOTE: in PyMuPDF CS, horizontal text direction is same with positive x-axis,
        # while vertical text is on the contrary, so use f = -1 here
        # 注意: 在PyMuPDF坐标系中，水平文本方向与正x轴相同，
        # 而垂直文本方向相反，所以这里使用f = -1
        idx, f = (0, 1.0) if self.is_horizontal_text else (3, -1.0)
        self.alignment = TextAlignment.LEFT
        self.left_space = (self.bbox[idx] - bbox[idx]) * f

    def store(self):
        """Store attributes in json format."""
        """以json格式存储属性。"""
        res = super().store()
        res.update(
            {
                "type": self._type.value,
                "alignment": self.alignment.value,
                "left_space": self.left_space,
                "right_space": self.right_space,
                "first_line_space": self.first_line_space,
                "before_space": self.before_space,
                "after_space": self.after_space,
                "line_space": self.line_space,
                "line_space_type": self.line_space_type,
                "tab_stops": self.tab_stops,
            }
        )
        return res

    def make_docx(self, *args, **kwargs):
        """Create associated docx element.

        Raises:
            NotImplementedError
        """
        """创建关联的docx元素。

        抛出:
            NotImplementedError
        """
        raise NotImplementedError
